package com.kjlink.widget.monitoring.helper;

import com.kjlink.common.base.tool.Tools;
import com.kjlink.common.util.JsonUtil;
import com.kjlink.widget.monitoring.config.ReportXmlDefaultProperties;
import com.kjlink.widget.monitoring.entity.MonitorEventBatch;
import com.kjlink.widget.monitoring.entity.MonitorRawEvent;
import com.kjlink.widget.monitoring.model.BaseMonitorDataExtraModel;
import com.kjlink.widget.monitoring.model.MonitorDataModel;
import com.kjlink.widget.monitoring.xml.AppRootXml;
import com.kjlink.widget.monitoring.xml.ReportContentXml;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;


/**
 * 描述:
 * 构件一些对象的工具类
 * 1.  构建要上报的数据的xml格式
 * 2. 把redis里的MonitorDataModel对象转化为数据库对象MonitorRawEvent
 *
 * @author Vic.xu
 * @since 2025-08-11 15:44
 */
@Component
public class MonitorModelBuilderHelper {

    @Resource
    private ReportXmlDefaultProperties reportXmlDefaultProperties;

    /**
     * 上传的日期格式
     */
    private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    /**
     * 构建xml格式数据
     */
    public AppRootXml buildXml(MonitorEventBatch batch) {
        Assert.notNull(batch, "batch can not be null");
        MonitorRawEvent firstRawEvent = batch.getFirstRawEvent();
        Assert.notNull(firstRawEvent, "firstRawEvent can not be null");
        // 1. 构建 PUBLIC 数据
        ReportContentXml publicData = new ReportContentXml();
        // 日期  压缩事件取周期内首次发生时间
        publicData.setDATE(batch.getFirstOccurTime().format(formatter));
        // 应用名称
        publicData.setAPPSNAME(reportXmlDefaultProperties.getAppName());
        // 监控类别
        publicData.setTYPE(firstRawEvent.getMonitorType());
        // 交易代码（条件必填）
        publicData.setTRANCODE(firstRawEvent.getTranCode());
        // 资源代码（条件必填）
        publicData.setRESOURCECODE(firstRawEvent.getResourceCode());
        // 错误代码（必填）
        publicData.setEVENTCODE(firstRawEvent.getEventCode());
        // 业务种类（非必填）
        publicData.setBUSINESSTYPE(firstRawEvent.getBusinessType());

        // 事件发生次数（必填）
        publicData.setEVENTSCOUNT(batch.getCount());
        // 发生地点（必填）
        publicData.setOCCURPLACE(firstRawEvent.getOccurPlace());
        // 业务源应用（非必填）
        publicData.setSOUCEAPPCODE(firstRawEvent.getSourceAppcode());
        // 业务目标应用（非必填）
        publicData.setTARGETAPPCODE(firstRawEvent.getTargetAppcode());
        // 业务异常情况（非必填）
        publicData.setEXCEPTION(firstRawEvent.getException());


        // 资源使用情况（非必填）
        publicData.setRESOURCERATE(null);

        // 发生容器/实例（非必填）
        publicData.setOCCURINSTANCE(null);

        // 上送应用服务群组ID
        publicData.setSUBAPPID(null);
        // 业务源应用服务群组ID
        publicData.setSOURCESUBAPPID(null);
        // 业务目标应用服务群组ID
        publicData.setTARGETSUBAPPID(null);
        // 备用字段
        publicData.setBAKUP(null);
        // 监控对象（非必填）
        publicData.setOBJECT(null);

        //2.  暂时无PRIVATE 数据
        // 3. 构建根对象
        AppRootXml rootXml = new AppRootXml(publicData);
        buildRootNodeAttribute(rootXml);
        return rootXml;
    }

    /**
     * 构建根节点属性
     */
    private void buildRootNodeAttribute(AppRootXml rootXml) {
        rootXml.setType(reportXmlDefaultProperties.getType());
        rootXml.setVer(reportXmlDefaultProperties.getVer());
        rootXml.setFrom(reportXmlDefaultProperties.getFrom());
        rootXml.setTo(reportXmlDefaultProperties.getTo());
        rootXml.setMode(reportXmlDefaultProperties.getMode());
    }

    /**
     * 将 MonitorDataModel 转换为数据库实体MonitorRawEvent
     * TODO 字段调整在这里
     */
    public MonitorRawEvent buildRawEvent(MonitorDataModel<? extends BaseMonitorDataExtraModel> dataModel) {
        MonitorRawEvent rawEvent = new MonitorRawEvent();

        // 设置事件ID（使用dataModel中的eventId）
        rawEvent.setEventId(dataModel.getEventId());

        // 事件类型（转换为字符串存储）
        rawEvent.setEventType(dataModel.getEventType().getCode());
        // 监控类型
        rawEvent.setMonitorType(dataModel.getMonitorType().getCode());

        // 事件源业务id
        String businessId = dataModel.getBusinessId();
        if (businessId == null) {
            businessId = Tools.randomUuid();
        }
        if (businessId.length() > 64) {
            businessId = StringUtils.abbreviate(businessId, 64);
        }
        rawEvent.setBusinessId(businessId);
        rawEvent.setBusinessType(dataModel.getBusinessType());
        // 创建人
        rawEvent.setCreatedBy(dataModel.getCreatedBy());

        // 事件数据
        rawEvent.setData(JsonUtil.toJson(dataModel.getExtra()));

        // 事件发生时间（优先使用dataModel中的时间，否则用当前时间）
        rawEvent.setOccurTime(dataModel.getOccurTime() != null ?
                dataModel.getOccurTime() : LocalDateTime.now());
        rawEvent.setOccurPlace(dataModel.getOccurPlace());

        // 入库时间（设置为当前时间）
        rawEvent.setCreateTime(LocalDateTime.now());

        // 错误代码（必填）
        rawEvent.setEventCode(dataModel.getEventCode());
        // 资源代码（条件必填）
        rawEvent.setResourceCode(dataModel.getResourceCode());
        // 交易代码（条件必填）
        rawEvent.setTranCode(dataModel.getTranCode());

        // 业务异常情况（非必填）
        rawEvent.setException(dataModel.getException());
        // 业务源应用（非必填）
        rawEvent.setSourceAppcode(dataModel.getSourceAppcode());
        // 业务目标应用（非必填）
        rawEvent.setTargetAppcode(dataModel.getTargetAppcode());

        return rawEvent;
    }

}
